home *** CD-ROM | disk | FTP | other *** search
/ Turnbull China Bikeride / Turnbull China Bikeride - Disc 2.iso / BARNET / ARMTEX / SOURCES1 / !TeX / texmf / source / armTeX / lib / c / riscos_ex < prev    next >
Encoding:
Text File  |  1998-04-06  |  9.5 KB  |  322 lines

  1. /*
  2.  * riscos_ex.c: RISC OS extras
  3.  * 
  4.  * Copyright (C) 1992 Free Software Foundation, Inc.
  5.  * 
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published
  8.  * by the Free Software Foundation; either version 2, or (at your
  9.  * option) any later version.
  10.  * 
  11.  * This program is distributed in the hope that it will be useful, but
  12.  * WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * General Public License for more details.
  15.  * 
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  * 
  20.  * This file contains functions that are lacking in Acorn ANSI C v4 or
  21.  * that are too RISC OS-specific to be simply changed in the relevant
  22.  * .c or .h files
  23.  * 
  24.  * All functions are prefixed by `riscos_' to avoid function name
  25.  * clashes
  26.  * 
  27.  * The author is Mark J. Sinke, reachable at marks@stack.urc.tue.nl or
  28.  * Mark J. Sinke Mendelssohnstraat 5 5144 GD WAALWIJK The Netherlands
  29.  * 
  30.  * Much code is rewritten by Jakob Stoklund Olesen <stoklund@mi.aau.dk>
  31.  */
  32.  
  33. #define RISCOS_EX_C_FILE
  34.  
  35. #include "config.h"
  36.  
  37. #include "OS:OSFSContro.h"
  38. #include "OS:OSFile.h"
  39.  
  40. /*
  41.  * This variable holds our impression of the CSD as set by
  42.  * riscossetname.
  43.  */
  44. char *current_prefix = "";
  45. int current_prefix_length = 0;
  46.  
  47. /*
  48.  * TeX and Metafont have two ways of creating output files with
  49.  * extensions: dot-mode: file is put in a directory. slash-mode:
  50.  * extension separator is '/'. The mode is determined by the filename
  51.  * conventions used by the input file.
  52.  */
  53. enum riscosoutputmode_enum riscosoutputmode = outputmode_unset;
  54.  
  55. /*
  56.  * This is the file type that is given to the next file opened for
  57.  * output.
  58.  */
  59. int riscostype = 0xfff;        /* Default to `text' output */
  60.  
  61.  
  62. /*--------------------------------------------------------------------------
  63.    riscos_absolute(filename): return true if file name is absolute
  64.    or explicitly relative
  65. --------------------------------------------------------------------------*/
  66. /* I think the following is sufficient; should look up PRMs */
  67. boolean
  68. riscos_absolute (char *filename)
  69. {
  70.   return (filename[0] == '-' || strpbrk (filename, ":$&\\@^") != NULL);
  71. }
  72.  
  73. /*--------------------------------------------------------------------
  74.    riscossetname(name): set `current prefix' to current dir
  75.  
  76.    If pathname is absolute (or explicitly relative) it is used to
  77.    find the root dir.
  78.    If it is relative, the current CSD is used.
  79.    The path is canonicalised to avoid later dependency on CSD settings.
  80.    The filename given must have an extension.
  81. --------------------------------------------------------------------*/
  82. void
  83. riscossetname (char *name)
  84. {
  85.   char *pos;
  86.   char *work;
  87.   char *pathend;
  88.   int size;
  89.  
  90.   null_terminate (name + 1);
  91.   work = name + 1;
  92. #ifdef RISCOS_DEBUG
  93.   fprintf (stderr, "riscos_setname(\"%s\")\n", work);
  94. #endif
  95.  
  96.   /* simple relative path: use CSD as prefix */
  97.   if (!riscos_absolute (work))
  98.     {
  99.       if (NULL == xosfscontrol_canonicalise_path ("@",
  100.                         NULL, NULL, NULL, 0, &size))
  101.     {
  102.       current_prefix = xmalloc (2 - size);
  103.       current_prefix_length = 1 - size;
  104.       /* Got the size, now get the path */
  105.       if (NULL == xosfscontrol_canonicalise_path ("@",
  106.                               current_prefix, NULL,
  107.                               NULL, 1 - size, &size)
  108.           && size == 1)
  109.         {
  110.           current_prefix[current_prefix_length - 1] = '.';
  111.           current_prefix[current_prefix_length] = '\0';
  112. #ifdef RISCOS_DEBUG
  113.           fprintf (stderr, "  --> set to \"%s\" (from CSD)\n",
  114.                current_prefix);
  115. #endif
  116.           return;        /* ok, got the path */
  117.         }
  118.       free (current_prefix);
  119.     }
  120.       /* getting here means some error occured */
  121.       current_prefix = "";
  122.       current_prefix_length = 0;
  123.       return;
  124.     }
  125.  
  126.   /* It's an absolute path */
  127.   current_prefix = NULL;
  128.   /* Find the size of the canonicalised path */
  129.   if (NULL == xosfscontrol_canonicalise_path (work, NULL,
  130.                           NULL, NULL, 0, &size))
  131.     {
  132.       current_prefix = xmalloc (1 - size);
  133.       /* Got the size, now get the path */
  134.       if (NULL != xosfscontrol_canonicalise_path (work, current_prefix,
  135.                         NULL, NULL, 1 - size, &size)
  136.       || size != 1)
  137.     {
  138.       /* Something went wrong */
  139.       free (current_prefix);
  140.       current_prefix = NULL;
  141.     }
  142.     }
  143.   /* If somehow OS_FSControl didn't work, we use the given name */
  144.   if (current_prefix == NULL)
  145.     current_prefix = xstrdup (work);
  146.  
  147.   /* Now strip off the filename to get the path */
  148.   pos = find_suffix (current_prefix);
  149.   if (pos)
  150.     *--pos = '\0';        /* there goes the extension */
  151.   else
  152.     pos = current_prefix + strlen (current_prefix);
  153.   /* Find the last '.' or ':' */
  154.   while (pos > current_prefix && pos[-1] != '.' && pos[-1] != ':')
  155.     pos--;
  156.   *pos = '\0';
  157.   current_prefix_length = pos - current_prefix;
  158.   /* If there's nothing left (unlikely) we use "" */
  159.   if (current_prefix_length == 0)
  160.     {
  161.       free (current_prefix);
  162.       current_prefix = "";
  163.     }
  164.  
  165. #ifdef RISCOS_DEBUG
  166.   fprintf (stderr, "  --> set to \"%s\" (from \"%s\")\n",
  167.        current_prefix, work);
  168. #endif
  169.   space_terminate (name + 1);
  170. }
  171.  
  172. /*--------------------------------------------------------------------
  173.    riscos_isdir(filename): return true if filename is a directory
  174. --------------------------------------------------------------------*/
  175.  
  176. /*
  177.  * OS_File 5: Read catalogue information for a named object (Using
  178.  * File$Path) Return 0 if not found, 1 if file, 2 if directory, 3 if
  179.  * image file
  180.  */
  181.  
  182. boolean
  183. riscos_isdir (char *filename)
  184. {
  185.   int length = strlen (filename);
  186.   char end = filename[length - 1];
  187.   int obj_type;
  188.  
  189.   if (end == '.')
  190.     filename[length - 1] = '\0';
  191.  
  192.   if (NULL != xosfile_read_stamped (filename, &obj_type,
  193.                     NULL, NULL, NULL, NULL, NULL))
  194.     obj_type = 0;
  195.  
  196.   filename[length - 1] = end;
  197.   return obj_type == 2 || obj_type == 3;    /* accept images as well */
  198. }
  199.  
  200. /*--------------------------------------------------------------------
  201.  riscos_translate(filename, create)
  202.  All the filename translation for RISC OS is handled by this function.
  203.  The current prefix is prepended to the path is necessary and the
  204.  extension delimiter is swapped between '.' and '/'. If create is true,
  205.  an empty file of type riscostype is created and possibly the necessary
  206.  directory. The string returned is malloc'ed and should be freed.
  207.  If no readable file could be found, or no file written NULL is returned.
  208. --------------------------------------------------------------------*/
  209.  
  210. char *
  211. riscos_translate (char *filename, boolean create)
  212. {
  213.   char *newname = NULL;        /* the string to return */
  214.   char *sufpos;            /* where is the suffix? */
  215.   int good;
  216.  
  217.   /* first we add the current prefix */
  218.   if (current_prefix_length > 0)
  219.     {
  220.       if (filename[0] == '@')
  221.     newname = concat (current_prefix, filename + 2);
  222.       else if (filename[0] == '^' || !riscos_absolute (filename))
  223.     newname = concat (current_prefix, filename);
  224.     }
  225.   if (!newname)
  226.     newname = xstrdup (filename);
  227.  
  228.   sufpos = find_suffix (newname);
  229.  
  230.   if (create)
  231.     {
  232.       /* Try to create the given filename w/o checking output mode */
  233.       good = xosfile_create_stamped (newname, riscostype, 0) == NULL;
  234.       /* didn't work, the rest depends on output mode */
  235.       if (!good && sufpos)
  236.     {
  237.       switch (riscosoutputmode)
  238.         {
  239.         case outputmode_slash:    /* try with a '/' extension */
  240.           sufpos[-1] = '/';
  241.           break;
  242.         case outputmode_dot:    /* try to create the output dir */
  243.         default:        /* this is also the default mode */
  244.           sufpos[-1] = '\0';    /* this is the dir name */
  245.           /* make to output directory. TeX directories have very
  246.              few entries, so ask for 8 in case some filesystem
  247.              takes notice. */
  248.           xosfile_create_dir (newname, 8);
  249.           sufpos[-1] = '.';    /* restore filename */
  250.           break;
  251.         }
  252.       /* Try again to make the file.
  253.          If it fails, the caller will have to notice */
  254.       good = xosfile_create_stamped (newname, riscostype, 0) == NULL;
  255.     }
  256. #ifdef RISCOS_DEBUG
  257.       fprintf (stderr, "Writing \"%s\", type %3x\n", newname, riscostype);
  258. #endif
  259.       if (good)
  260.     riscostype = 0xfff;
  261.     }
  262.   else
  263.     /* not create */
  264.     {
  265.       /* First see if given filename exist */
  266.       good = riscos_readaccess (newname);
  267.       /* else try the opposite suffix delimiter */
  268.       if (!good && sufpos)
  269.     {
  270.       sufpos[-1] = sufpos[-1] == '.' ? '/' : '.';
  271.       good = riscos_readaccess (newname);
  272.     }
  273.       /* If this works, we set the output mode accordingly */
  274.       if (good && riscosoutputmode == outputmode_setnextread)
  275.     {
  276.       riscosoutputmode = sufpos[-1] == '.'
  277.         ? outputmode_dot : outputmode_slash;
  278. #ifdef RISCOS_DEBUG
  279.       fprintf (stderr, "Output mode set from \"%s\"\n", sufpos - 1);
  280. #endif
  281.     }
  282.     }
  283.  
  284.   if (good)
  285.     return newname;
  286.   else
  287.     {
  288.       free (newname);
  289.       return NULL;
  290.     }
  291. }
  292.  
  293.  
  294. /*--------------------------------------------------------------------
  295.   riscos_fopen(filename, mode): open a file for output, possibly
  296.   creating a directory and dealing with '@' This function replaces
  297.   all fopen()'s in TeX and friends! Note that it does not handle "a"
  298.   mode well w.r.t filetypes. I don't think that it is used.
  299. --------------------------------------------------------------------*/
  300.  
  301. FILE *
  302. riscos_fopen (char *filename, char *mode)
  303. {
  304.   FILE *f;
  305.   char *newname;
  306.  
  307.   newname = riscos_translate (filename, mode[0] == 'w');
  308.   if (newname != NULL)
  309.     {
  310.       f = fopen (newname, mode);
  311.       free (newname);
  312.       return f;
  313.     }
  314.   else
  315.     {
  316.       /* some programs need to open null: which fails above */
  317.       if (0 == strncmp (filename, "null:", 5))
  318.     return fopen ("null:", mode);
  319.       return NULL;
  320.     }
  321. }
  322.